package com.wedo.mall.activity.login;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.util.Log;

import com.e.library.activity.EActivity;
import com.e.library.entity.User;
import com.e.library.http.EClient;
import com.e.library.http.EObserver;
import com.e.library.http.EResponse;
import com.e.library.utils.EGsonUtils;
import com.e.library.utils.ESPUtils;
import com.facebook.AccessToken;
import com.facebook.AccessTokenTracker;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.GraphRequest;
import com.facebook.GraphResponse;
import com.facebook.Profile;
import com.facebook.login.LoginManager;
import com.facebook.login.LoginResult;
import com.hyphenate.EMCallBack;
import com.hyphenate.chat.EMClient;
import com.wedo.mall.R;
import com.wedo.mall.WApp;
import com.wedo.mall.WService;
import com.wedo.mall.activity.LoginActivity;

import org.json.JSONObject;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import cn.sharesdk.facebook.Facebook;
import cn.sharesdk.framework.Platform;
import cn.sharesdk.framework.PlatformActionListener;
import cn.sharesdk.framework.ShareSDK;
import cn.sharesdk.wechat.friends.Wechat;
import io.reactivex.Observable;

/**
 * 登录相关
 * Created by e on 2017/7/2.
 */

public final class WLogin {

    public static final String TAG = "login";
    public static final String USER = "user";
    public static final String USERNAME = "username";
    public static final String PASSWORD = "password";
    /**------第三方登录-----**/
    private static final String AUTH_LOGIN = "auth_login";
    private static final String AUTH_PARAMS = "auth_params";

    public WLogin(){
        facebook();
    }

    public static WLogin with(){
        return new WLogin();
    }

    /**已登录，则启动服务启动登录*/
    public static void tryLogin(Context context){
        if (logged(context)){
            WService.login(context);
        }
    }

    /**是否绑定邮箱*/
    public static boolean isBinding(Context context) {
        User user = user(context);
        if (user != null && user.isBindingEmail()) {
            return true;
        }
        Intent intent = new Intent(context,BindingActivity.class);
        context.startActivity(intent);
        return false;
    }

    /**是否绑定邮箱*/
    public static boolean isBinding(EActivity activity) {
        User user = user(activity);
        if (user != null && user.isBindingEmail()) {
            return true;
        }
        activity.toActivity(BindingActivity.class);
        return false;
    }

    public static User user(){
        return user(WApp.app());
    }

    public static User user(Context context){
        String str = ESPUtils.getString(context,USER,"");
        if (!TextUtils.isEmpty(str)){
            return EGsonUtils.toObject(str,User.class);
        }
        return null;
    }

    public static void saveUser(Context context,User user){
        ESPUtils.setString(context,USER,user.toString());
    }

    /**如果没有登录*/
    public static boolean isLogged(EActivity activity){
        if (!logged(activity.getApplicationContext())){
            Bundle bundle = new Bundle();
            bundle.putInt(LoginActivity.EXTRA_ENDPOINT,LoginActivity.ENDPOINT_MAIN);
            activity.toActivity(LoginActivity.class,bundle);
            return false;
        }
        return true;
    }

    public static boolean logged(Fragment fragment){
        return logged(fragment.getContext());
    }

    public static boolean logged(Context context){
        if(isAuth(context)) {// auth login
            return EMClient.getInstance().isLoggedInBefore();
        }

        String username = ESPUtils.getString(context,USERNAME);
        String password = ESPUtils.getString(context,PASSWORD);
        return !TextUtils.isEmpty(username) && !TextUtils.isEmpty(password) && EMClient.getInstance().isLoggedInBefore();
    }

    /**退出登录*/
    public static void logout(Context context){
        ESPUtils.setString(context,PASSWORD,"");
        ESPUtils.setString(context,PASSWORD,"");
        /**------auth login-----**/
        ESPUtils.setString(context,AUTH_PARAMS,"");
        ESPUtils.setboolean(context,AUTH_LOGIN,false);

        EClient.with().clearSession(context);
        EMClient.getInstance().logout(false);
    }

    public void auto(Context context){
        if(isAuth(context)) {
            /**------auth login-----**/
            String params = ESPUtils.getString(context,AUTH_PARAMS);
            Map<String,String> map = EGsonUtils.toObject(params,Map.class);
            auth(context,map);
            return;
        }

        String username = ESPUtils.getString(context,USERNAME);
        String password = ESPUtils.getString(context,PASSWORD);
        login(context,username,password);
    }

    public void login(final Context context, final String username, final String password){
        Observable<EResponse> observable = EClient.with().api().login(username,password);
        EClient.with().observer(observable, new EObserver() {
            @Override
            public void successful(EResponse response) {
                User user = response.user();
                String userId = response.string("userId");
                onLogged(context,username,password,user);
                loginEase(context,user,userId);
            }

            @Override
            public void failure(String msg) {
                onLoginFailure(context,msg);
            }

            @Override
            public void onComplete() {

            }
        });
    }

    private void onLoginSuccess(User user){
        if (listener !=null){
            listener.successful(user);
        }
    }

    private void onLoginFailure(final Context context,String msg){
        if (listener!=null){
            listener.failure(msg);
        }
        logout(context);
    }


    /***
     * 环信登录规则
     * 账号：wedo+ 用户id
     * 密码：wedo+ 用户id
     * @param user
     * @param userId 用于环信登录
     */
    private void loginEase(final Context context,final User user,String userId){
        String username = "wedo"+userId;

        EMClient.getInstance().login(username,username,new EMCallBack(){
            @Override
            public void onSuccess() {
                Log.i(TAG,"登录环信成功");
                onLoginSuccess(user);
            }

            @Override
            public void onError(int i, String s) {

                StringBuilder msg = new StringBuilder();
                msg.append(context.getResources().getString(R.string.login_failure))
                        .append(",").append(s).append("(").append(i).append(")");
                Log.i(TAG, msg.toString());
                onLoginFailure(context,msg.toString());
            }

            @Override
            public void onProgress(int i, String s) {

            }
        });

    }

    private void onLogged(Context context,String username,String password,User user){
        ESPUtils.setString(context,USERNAME,username);
        ESPUtils.setString(context,PASSWORD,password);
        ESPUtils.setboolean(context,AUTH_LOGIN,false);
        saveUser(context,user);
    }

    private LoginListener listener;
    public WLogin listener(LoginListener listener){
        this.listener = listener;
        return this;
    }
    public interface LoginListener{
        void loading();
        void successful(User user);
        void failure(String msg);
    }

    /**-----------------facebook-----------------**/

    private AccessTokenTracker mFacebookTokenTracker = new AccessTokenTracker() {
        @Override
        protected void onCurrentAccessTokenChanged(AccessToken oldAccessToken, AccessToken currentAccessToken) {
        }
    };

    private CallbackManager mFacebookCallback;
    private void facebook(){
        mFacebookCallback = CallbackManager.Factory.create();
        LoginManager.getInstance().registerCallback(mFacebookCallback,
                new FacebookCallback<LoginResult>() {
                    @Override
                    public void onSuccess(LoginResult loginResult) {
                        //Facebook 授权登录成功
                        facebookRequest();
                    }

                    @Override
                    public void onCancel() {
                        Log.i(TAG,"onCancel");
                    }

                    @Override
                    public void onError(FacebookException exception) {
                        Log.i(TAG,"onError");
                        exception.printStackTrace();
                        if (listener != null){
                            listener.failure(exception.getMessage());
                        }

                    }
                });
    }

    private void facebookRequest(){
        AccessToken token = AccessToken.getCurrentAccessToken();
        Log.i(WLogin.TAG, token.toString());
        GraphRequest request = GraphRequest.newMeRequest(token, new GraphRequest.GraphJSONObjectCallback() {
                    @Override
                    public void onCompleted(JSONObject object, GraphResponse response) {
                        try {
                            Log.i(TAG, object.toString());

                            if (response.getError() != null && listener != null) {
                                listener.failure(response.getError().getErrorMessage());
                                return;
                            }

                            Profile profile = Profile.getCurrentProfile();
                            if(profile !=null) {

                            }
                            String id = object.optString("id");
                            String name = object.optString("name");
                            String gender = object.optString("gender","male");
                            String avatar = object.getJSONObject("picture").getJSONObject("data").getString("url");

                            int sex = 0;//女
                            if(TextUtils.equals("male",gender)) {
                                sex = 1;//男
                            }

                            Map<String,String> params = new HashMap<>(7);
                            params.put("openid",id);
                            params.put("headimgurl",avatar);
                            params.put("nickname",name);
                            params.put("sign","facebook");
                            params.put("sex",String.valueOf(sex));

                            if (object.has("email")){
                                String email = object.getString("email");
                                params.put("email",email);
                            }

                            Log.i(TAG,params.toString());

                            auth(WApp.app(),params);

                        }catch (Exception e){
                            e.printStackTrace();
                            if (listener != null){
                                listener.failure(e.getMessage());
                            }
                        }
                    }
                });
        Bundle parameters = new Bundle();
        parameters.putString("fields", "id,name,picture,email,gender");
        request.setParameters(parameters);
        request.executeAsync();
    }

    public void facebook(Activity activity){
        //auth(activity,ShareSDK.getPlatform(Facebook.NAME));
        /**------为获取Facebook email-----**/
        LoginManager.getInstance().logOut();
        LoginManager.getInstance().logInWithReadPermissions(activity, Arrays.asList("email","public_profile"));
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        mFacebookCallback.onActivityResult(requestCode, resultCode, data);
    }

    public void onDestroy() {
        mFacebookTokenTracker.stopTracking();
    }

    /**-----------------第三方登录-----------------**/
    public void wechat(Context context){
        auth(context,ShareSDK.getPlatform(Wechat.NAME));
    }

    /**----------第三方SDK登录授权------------------*/
    private void auth(final Context context, final Platform plat) {
        if (plat.isAuthValid()){
            plat.removeAccount(true);
        }
        plat.setPlatformActionListener(new PlatformActionListener() {
            @Override
            public void onComplete(Platform platform, int action, HashMap<String, Object> hashMap) {
                if (action == Platform.ACTION_USER_INFOR) {

                    Map<String,String> params = new HashMap<>(5);

                    String token = platform.getDb().getToken();
                    String userid = platform.getDb().getUserId();//openid
                    String avatar = platform.getDb().getUserIcon();

                    params.put("openid",userid);
                    params.put("headimgurl",avatar);

                    String name = platform.getName();
                    if (TextUtils.equals(Wechat.NAME, name)) {

                        params.put("unionid",hashMap.get("unionid").toString());
                        params.put("nickname",hashMap.get("nickname").toString());
                        params.put("sign","wechat");
                        params.put("sex",hashMap.get("sex").toString());

                    } else if (TextUtils.equals(Facebook.NAME,name)){
                        params.put("nickname",hashMap.get("name").toString());
                        params.put("sign","facebook");
                        String json = EGsonUtils.toJson(hashMap);
                        Log.i(TAG,json);
                    }

                    String result = hashMap.toString();
                    Log.i(TAG,result);
                    Log.i(TAG,params.toString());

                    auth(context,params);
                }
            }

            @Override
            public void onError(Platform platform, int action, Throwable t) {
                t.printStackTrace();
                if (action == Platform.ACTION_USER_INFOR) {
                    String failure = context.getResources().getString(R.string.auth_failure);
                    sendMessage(MSG_FAILURE,failure);
                }
            }

            @Override
            public void onCancel(Platform platform, int action) {
            }
        });
        //关闭SSO授权
        plat.SSOSetting(false);
        plat.showUser(null);
    }

    public static boolean isAuth(Context context){
        boolean auth = ESPUtils.getBoolean(context,AUTH_LOGIN,false);
        String params = ESPUtils.getString(context,AUTH_PARAMS);
        return auth && !TextUtils.isEmpty(params);
    }

    /**------第三方登录-----**/
    private void auth(final Context context, final Map<String,String> params){
        if (listener != null) {
            listener.loading();
        }
        Observable<EResponse> observable = EClient.with().api().auth(params);
        EClient.with().observer(observable, new EObserver() {
            @Override
            public void successful(EResponse response) {
                User user = response.user();
                String userId = response.string("userId");
                ESPUtils.setString(context,USER,user.toString());
                ESPUtils.setString(context,AUTH_PARAMS,EGsonUtils.obj2Json(params));
                ESPUtils.setboolean(context,AUTH_LOGIN,true);
                loginEase(context,user,userId);
            }

            @Override
            public void failure(String msg) {
                onLoginFailure(context,msg);
            }

            @Override
            public void onComplete() {

            }
        });
    }

    private static final int MSG_SUCCESS = 1;
    private static final int MSG_FAILURE = 2;
    private Handler handler = new Handler(Looper.getMainLooper()){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if(listener == null) {
                return;
            }

            if(msg.what == MSG_SUCCESS) {
                User user = (User) msg.obj;
                listener.successful(user);
            } else if(msg.what == MSG_FAILURE) {
                if(msg.obj == null) {
                    String failure = WApp.app().getResources().getString(R.string.login_failure);
                    listener.failure(failure);
                    return;
                }
                listener.failure(msg.obj.toString());
            }
        }
    };

    private void sendMessage(int what,Object data){
        Message message = handler.obtainMessage(what);
        message.what = what;
        message.obj = data;
        handler.sendMessage(message);
    }

}
